package org.dmcs.linguistics.labs.parkingmeter;

import java.util.Map;

import org.dmcs.linguistics.labs.parkingmeter.input.symbols.SymbolStatePair;

/**
 * Ogolny detewrministyczny automat skonczony.
 * @author Zielony
 * @version 1.0
 * @param <InputSymbolType> typ symboli przyjmowanych przez automat.
 * @param <StateType> typ stanow wewnetrznych automatu.
 */
public class DeterministicFiniteAutomaton<InputSymbolType extends Enum, StateType extends Enum> implements IAutomaton<InputSymbolType, StateType> {
	/**
	 * Tabela opisujaca funkcje przejsc automatu.
	 */
	private Map<SymbolStatePair<InputSymbolType, StateType>, StateType> transitionTable;
	
	/**
	 * Obecny stan automatu.
	 */
	private StateType currentState;
	
	/**
	 * Tworzy automat z podanym stanem poczatkowym i podana tabela przejsc.
	 * @param initialState stan poczatkowy automatu.
	 * @param transitionTable tabela opisujaca funkcje przejsc automatu/.
	 */
	public DeterministicFiniteAutomaton(StateType initialState, 
			Map<SymbolStatePair<InputSymbolType, StateType>, StateType> transitionTable) {
		this.currentState = initialState;
		this.transitionTable = transitionTable;
	}
	
	/* (non-Javadoc)
	 * @see org.dmcs.linguistics.labs.parkingmeter.IAutomaton#acceptSymbol(InputSymbolType)
	 */
	public StateType acceptSymbol(InputSymbolType inputSymbol) {
		/*
		 * Para, przy pomocy ktorej pytamy o kolejny symbol
		 */
		SymbolStatePair queryPair = new SymbolStatePair(inputSymbol, currentState);
		
		/*
		 * Przypisanie wyniku przejscia jako obecnego stanu automatu.
		 */
		this.currentState = transitionTable.get(queryPair);
		
		return this.currentState;
	}
	
	/* (non-Javadoc)
	 * @see org.dmcs.linguistics.labs.parkingmeter.IAutomaton#getCurrentState()
	 */
	public StateType getCurrentState() {
		return currentState;
	}
}